package com.swing_pinea.render;

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;

public class PineaImage {
    // 存储图像的原始数据
    private BufferedImage data;
    // 图像宽度
    private int width;
    // 图像高度
    private int height;
    
    public PineaImage(BufferedImage data) {
        this.data = data;
        this.width = data.getWidth();
        this.height = data.getHeight();
    }
    
    public BufferedImage getData() {
        return data;
    }
    
    public int getWidth() {
        return width;
    }
    
    public int getHeight() {
        return height;
    }

    /**
     * 缩放图像
     *
     * @param x X 轴方向缩放比例
     * @param y Y 轴方向缩放比例
     * @return 缩放后的新 PineaImage 对象
     */
    public PineaImage scale(float x, float y) {
        // 创建缩放变换操作，使用最近邻插值
        AffineTransformOp op = new AffineTransformOp(
                AffineTransform.getScaleInstance(x, y), AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
        // 执行变换并返回新图像对象
        return new PineaImage(op.filter(data, null));
    }

    /**
     * 旋转图像
     *
     * @param angle 旋转角度（度）
     * @return 旋转后的新 PineaImage 对象
     */
    public PineaImage rotate(double angle) {
        // 创建旋转变换操作，围绕图像中心旋转，使用最近邻插值
        AffineTransformOp op = new AffineTransformOp(
                AffineTransform.getRotateInstance(Math.toRadians(angle),
                        data.getWidth() >> 1, // 图像中心 X 坐标（右移 1 位等价于除以 2）
                        data.getHeight() >> 1), // 图像中心 Y 坐标
                AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
        // 执行变换并返回新图像对象
        return new PineaImage(op.filter(data, null));
    }

    /**
     * 翻转图像（水平、垂直或同时翻转）
     *
     * @param flipX 是否水平翻转
     * @param flipY 是否垂直翻转
     * @return 翻转后的新 PineaImage 对象
     */
    public PineaImage flip(boolean flipX, boolean flipY) {
        // 若无需翻转，返回原图像的副本
        if (!flipX && !flipY) {
            return new PineaImage(copyImage(data));
        }
        int width = data.getWidth();
        int height = data.getHeight();
        // 创建仿射变换对象
        AffineTransform transform = new AffineTransform();
        // 同时水平和垂直翻转
        if (flipX && flipY) {
            transform.scale(-1, -1); // 同时翻转 X 和 Y 轴
            transform.translate(-width, -height); // 平移补偿，使图像完整显示
        } else if (flipX) {
            // 仅水平翻转
            transform.scale(-1, 1); // 翻转 X 轴
            transform.translate(-width, 0); // X 方向平移补偿
        } else {
            // 仅垂直翻转
            transform.scale(1, -1); // 翻转 Y 轴
            transform.translate(0, -height); // Y 方向平移补偿
        }
        // 创建变换操作，使用双线性插值提升质量
        AffineTransformOp op = new AffineTransformOp(
                transform,
                AffineTransformOp.TYPE_BILINEAR
        );
        // 创建目标图像并执行变换
        BufferedImage flippedImage = new BufferedImage(
                width,
                height,
                data.getType()
        );
        op.filter(data, flippedImage);
        return new PineaImage(flippedImage);
    }

    /**
     * 裁剪图像
     *
     * @param x      裁剪起始 X 坐标
     * @param y      裁剪起始 Y 坐标
     * @param width  裁剪宽度
     * @param height 裁剪高度
     * @return 裁剪后的新 PineaImage 对象
     */
    public PineaImage crop(int x, int y, int width, int height) {
        // 获取子图像并创建副本（避免与原图共享数据）
        return new PineaImage(copyImage(data.getSubimage(x, y, width, height)));
    }

    /**
     * 复制图像，创建独立的图像副本
     *
     * @param source 源图像
     * @return 复制后的新图像
     */
    private BufferedImage copyImage(BufferedImage source) {
        BufferedImage copy = new BufferedImage(
                source.getWidth(),
                source.getHeight(),
                source.getType()
        );
        // 绘制图像完成复制
        copy.getGraphics().drawImage(source, 0, 0, null);
        return copy;
    }
}